﻿using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;

namespace Peony
{

    //网络收发
    public class Terminal
    {

        public bool Connected 
        {
            get
            {
                return _socket.Connected;
            }
        }
        
        TcpClient            _socket;
        private ByteBuffer   _inBuff;

        public delegate void ReadCallback(ByteBuffer buffer);

        private ReadCallback _readCallback;
        public Terminal(ReadCallback readCallback)
        {
            _socket = new TcpClient();
            _socket.NoDelay = true;

            _inBuff = new ByteBuffer();
            
            _readCallback = readCallback;
        }

        #region 连接,读取,发送
        public void ConnectTo(string remoteip,int remoteport)
        {
            _socket.BeginConnect(remoteip, remoteport, (IAsyncResult ar) =>
            {
                if (ar.IsCompleted)
                {
                    _socket.EndConnect(ar);
                    //尝试读取消息
                    KeepReadingPacket();
                }
            }, null);
        }
        
        private void KeepReadingPacket()
        {
            if (!Connected)
                return;

            byte[] tmp = new byte[_socket.ReceiveBufferSize];
            Array.Clear(tmp, 0, tmp.Length);
            _socket.GetStream().BeginRead(tmp, 0, tmp.Length, (IAsyncResult ar) =>
            {
                long nowms = Peony.Tool.GetTimeStamp();
                byte[] recvbuf = (byte[])ar.AsyncState;
                if (_socket.GetStream().CanRead == false) return;
   
                try
                {
                    int numberOfReadBytes = _socket.GetStream().EndRead(ar);
                    if (numberOfReadBytes == 0)
                    {
                        _socket.Close();
                        Tool.PrintLog(string.Format("读取错误，断开连接 在 {0}内", "ReadingPacketContent()"));
                    }
                    
                    _inBuff.putByte(recvbuf,numberOfReadBytes);
                    _readCallback(_inBuff);
                    Tool.PrintLog(string.Format("KeepReadingPacket time {0}", Tool.GetTimeStamp()-nowms));
                }
                catch(IOException ioe)
                {
                    Tool.PrintLog(ioe.ToString());                
                }
                KeepReadingPacket();
            },tmp);
        }

        public void SendData(byte[] data, int size)
        {
            if (!Connected) return;

            NetworkStream nstream = _socket.GetStream();

            if (!nstream.CanWrite) return;

            nstream.BeginWrite(data,0, size, 
                (IAsyncResult ar) =>
            {
                _socket.GetStream().EndWrite(ar);
            }, null);
        }

        public void CloseSocket()
        {
            if(Connected)
            {
                Tool.PrintLog("CloseSocket!!!");
                _socket.Close();
            }
        }
        #endregion

    }
}
